#! /usr/bin/env python3
import argparse
import yaml
import logging
import logging.handlers
from aiohttp import web
from handler import Handler
import os
from mongo import Mongo
from json_encoder import JSONEncoder
from raven.handlers.logging import SentryHandler
from libstorage.upyun_storage import Upyun


def arg_parse():
    # parse command line options
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--config', default='conf/wordbook.yml', type=argparse.FileType('r'))
    parser.add_argument('-i', '--interface', default='0.0.0.0', help='listen on [%(default)s]')
    parser.add_argument('-p', '--port', default=3224, help='bind to [%(default)s]')
    args = parser.parse_args()
    return args


def log_config(args, conf):
    log_level = getattr(logging, conf['logging']['level'])
    log_dir = os.path.join(conf['logging']['dir'])
    os.makedirs(log_dir, exist_ok=True)
    # -
    log_format = '[%(levelname)s]%(module)s->%(funcName)s: %(message)s --- %(asctime)s'
    log_formatter = logging.Formatter(log_format)
    # - stream
    logstream_handler = logging.StreamHandler()
    logstream_handler.setLevel(log_level)
    logstream_handler.setFormatter(log_formatter)
    # - rotating file
    logrot_handler = logging.handlers.TimedRotatingFileHandler(os.path.join(log_dir, conf['logfile']), when='midnight', interval=1, backupCount=5)
    logrot_handler.setLevel(log_level)
    logrot_handler.setFormatter(log_formatter)
    # - fluentd TODO
    # -
    logger = logging.getLogger()
    logger.setLevel(log_level)
    logger.addHandler(logstream_handler)
    logger.addHandler(logrot_handler)


def mongo_setup(conf):
    m = Mongo(host=conf['mongo']['host'],
              user=conf['mongo']['user'],
              passwd=conf['mongo']['passwd'],
              port=conf['mongo']['port'],
              db=conf['mongo']['db']
              )
    return m



async def cors_middleware_factory(app, handler):
    async def cors_handler(request):
        response = (await handler(request))
        response. headers['Access-Control-Allow-Origin'] = '*'
        response.headers['Access-Control-Allow-Headers'] = 'Authorization,Content-Type,Accept,Origin,User-Agent,'\
            'DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since'
        return response
    return cors_handler


def main():
    args = arg_parse()
    conf = yaml.load(args.config)
    log_config(args, conf)

    handler = Handler()
    middlewares = []
    if conf['cors_support'] is True:
        middlewares.append(cors_middleware_factory)
    app = web.Application(middlewares=middlewares)
    app['mongo'] = mongo_setup(conf)
    app['upyun'] = upyun_setup(conf)
    app['json_encoder'] = JSONEncoder()

    app.router.add_route('GET', '/', handler.HelloHandler)
    app.router.add_route('POST', '/en/words',handler.HelloHandler)
    app.router.add_route('GET', '/en/words', handler.HelloHandler)

    if conf['cors_support'] is True:
        app.router.add_route('OPTIONS', '/v1/tingdans/{id:[0-9a-zA-Z]+}', handler.CORSPutMethod)
        app.router.add_route('OPTIONS', '/v1/tingdans/{id:[0-9a-zA-Z]+}/purge', handler.CORSPutMethod)

    web.run_app(app, host=args.interface, port=args.port)

if __name__ == '__main__':
    main()
